//
//  GameControlLayer.m
//  AngerDragon
//
//  Created by gaotime_macbook_2 on 11-12-6.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "ScreenGameControlLayer.h"
#import "ScreenSpritesLayer.h"
#import "ScreenGameInfoShowLayer.h"

/// 数据固化层协议
#import "TYDataSolidifyProtocol.h"
#import "TYDataSolidifySingleton.h"
/// 剧本解析层协议
#import "TYScenarioInterpretationProtocol.h"
#import "TYScenarioInterpretationSingleton.h"
/// 地图层协议
#import "TYMapProtocol.h"
/// 精灵层协议
#import "TYSpriteLayerProtocol.h"
#import "TYSpriteLayerSingleton.h"

/// 状态机
#import "TYStateSystem.h"

  

// By adding another @interface with the same name of the class but adding an identifier in brackets
// you can define private class methods. 
// 通过添加和现有类同名的 @interface, 可以实现定义私有的方法.
// These are methods which are only used in this class and should not be used by other classes. 
// 这些方法只能用于当前类, 而不能被其他类使用.
// Adding these method definitions gets rid of the "may not respond to selector" warning messages. 
// 添加这些方法, 可以摆脱"可能不响应选择器"这种警告信息.
// The warning messages are not the problem, the problem is when the warning holds true
// and one of the selectors really can't respond. 
// 这个警告信息不是问题, 问题是当警告成立, 真的有一个选择器不响应的时候.
// Typically due to a spelling mistake. In that case the App would simply crash.
// 通常是由于拼写错误.在这种情况下, 应用会简单的崩溃.
// It's good practice to get rid of "may not respond to selector" warnings since they can
// be important indicators to potential crashes.
// 我们这里的做法, 是一种很好的摆脱 "可能不响应选择器" 的方法.因为他们可以作为潜在的崩溃的重要指示.

/// 这里用到 "类别" 来定义私有的方法
@interface ScreenGameControlLayer (GameControlLayerPrivateMethods)
 
@end

static ScreenGameControlLayer *m_p_screen_game_control_layer;
@implementation ScreenGameControlLayer

@synthesize m_state;

#pragma mark 游戏控制层对外通信的接口
+ (NSInteger) getState {
	NSAssert(m_p_screen_game_control_layer != nil, @"m_p_screen_game_control_layer is nil!");
	return [m_p_screen_game_control_layer.m_state getCurrentlyState];
}
+ (void) setState:(NSInteger) a_n_state {
	NSAssert(m_p_screen_game_control_layer != nil, @"m_p_screen_game_control_layer is nil!");
	
	[m_p_screen_game_control_layer.m_state setState:a_n_state];
}
#pragma mark ---------------------

- (id) init {
	
	if ((self = [super init]))
	{
		CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
		m_p_screen_game_control_layer = self;/// 实现伪单例
		
		/// 挂接状态机系统
		m_state = [[TYStateSystem alloc] init];
		/// 第一个状态是加载游戏相关资源
		[m_state setState:kGameMainState_Loading];
		
		// Yes, we want to receive accelerometer input events.
		/// 启用加速计
		self.isAccelerometerEnabled = YES;
		/// 激活触摸控制
		self.isTouchEnabled = YES;
		
		
		/// 设置在每一帧都运行的预约方法
		// scheduling the update method in order to adjust the player's speed every frame
		[self scheduleUpdate];
	}
	
	return self;
}

- (void) dealloc {
	CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
	
	m_p_screen_game_control_layer = nil;
	
	[m_state deallocMe];
	[super dealloc];
}

#pragma mark update
/// 每fps都调用
-(void) update:(ccTime)delta {
	
	switch ([m_state getCurrentlyState]) {
			
		/// 加载游戏相关资源
		case kGameMainState_Loading:
		{
			/// 加载本关地图图片和地图信息文件
			/// 加载本关动画精灵图片和动画精灵索引文件
			/// 加载本关剧本文件
			/// 创建player对象
			
			/// test
			{
				/// 创建一个player对象, 添加进ScreenSpritesLayer
				[[ScreenSpritesLayer sharedScreenSpritesLayer] addChild:(CCNode *)[TYPlayer getPlayerCommunicateProtocol]];
			}
			//[m_state setState:kGameMainState_Running];
		}break;

		/// 游戏运行状态
		case kGameMainState_Running:
		{
			/// 根据player状态, 判断游戏是否失败
			if ([[TYPlayer getPlayerCommunicateProtocol] player_isDead]) {
				/// player已经死亡, 本次游戏失败 				 
				[m_state setState:kGameMainState_CurrentGameOver];
				
				return;
			}
			
			/// 根据本关中所有敌对精灵是否被全部消灭, 来判断游戏是否胜利
			if ([[TYScenarioInterpretationSingleton sharedInstance] isWin]) {
				[m_state setState:kGameMainState_CurrentGameWin];
				return;
			}
			
			/// 调用剧本解读层 循环(根据时间轴 创建新的精灵)
			[[TYScenarioInterpretationSingleton sharedInstance] scenarioInterpretationLoop:delta];
			/// 调用地图层 循环(让地图运动)
		  //[m_map_protocol mapLoop:delta];
			/// 调用精灵层 循环
		  [[TYSpriteLayerSingleton sharedInstance] spriteLayerLoop:delta];
			
		}break;
			
		/// 本次游戏失败
		case kGameMainState_CurrentGameOver:
		{
			/// 本次游戏失败, 要根据具体情况来决定下一步
			/// ??? 这里策划必须给出明确的游戏方法才可以最后定格, 定格后后期不做变化

			if ([[TYPlayer getPlayerCommunicateProtocol] player_getContinueGameTime] <= 0) {
				/// 没有游戏次数了, 彻底失败
				[m_state setState:kGameMainState_GameOver];
			} else {
				/// 询问玩家是否要继续游戏
			}
		}break;
			
		/// 本次游戏胜利
		case kGameMainState_CurrentGameWin:
		{
			
			/// 返回 关卡选择 界面
		}break;
			
		/// 暂停
		case kGameMainState_Pause:
		{
		}break;
			
		/// 退出游戏运行窗口, 保存相关数据
		case kGameMainState_Quit:
		{
		}break;
//		case <#constant#>:
//		{
//		}break;
//		case <#constant#>:
//		{
//		}break;
			 
		default:
		{
		}break;
	}
	
}





// #pragma mark statements are a nice way to categorize your code and to use them as "bookmarks"
#pragma mark 加速计输入(Accelerometer Input)

-(void) accelerometer:(UIAccelerometer *) accelerometer 
				didAccelerate:(UIAcceleration *) acceleration {
	// These three values control how the player is moved. I call such values "design parameters" as they 
	// need to be tweaked a lot and are critical for the game to "feel right".
	// Sometimes, like in the case with deceleration and sensitivity, such values can affect one another.
	// For example if you increase deceleration, the velocity will reach maxSpeed faster while the effect
	// of sensitivity is reduced.
	
	/*
	// this controls how quickly the velocity decelerates (lower = quicker to change direction)
	float deceleration = 0.4f;
	// this determines how sensitive the accelerometer reacts (higher = more sensitive)
	float sensitivity = 6.0f;
	// how fast the velocity can be at most
	float maxVelocity = 100;
	
	// adjust velocity based on current accelerometer acceleration
	playerVelocity.x = playerVelocity.x * deceleration + acceleration.x * sensitivity;
	
	// we must limit the maximum velocity of the player sprite, in both directions (positive & negative values)
	if (playerVelocity.x > maxVelocity)
	{
		playerVelocity.x = maxVelocity;
	}
	else if (playerVelocity.x < -maxVelocity)
	{
		playerVelocity.x = -maxVelocity;
	}
	
	// Alternatively, the above if/else if block can be rewritten using fminf and fmaxf more neatly like so:
	// playerVelocity.x = fmaxf(fminf(playerVelocity.x, maxVelocity), -maxVelocity);
	
	
	player.position.x += acceleration.x * 10;
	 */
}

#pragma mark 注册触摸事件代理
-(void) registerWithTouchDispatcher {
	[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self 
																									 priority:-1     /// 优先权
																						swallowsTouches:YES];  /// 是否接收全部触摸点
}

#pragma mark 
#pragma mark Layer - Callbacks

#pragma mark ccTouchesBegan方法
-(BOOL) ccTouchBegan:(UITouch *)touch 
					 withEvent:(UIEvent *)event {
						  
	/// 真实的触摸点坐标
	//CGPoint a_st_true_touch_location = [touch locationInView: [touch view]];
	/// 引擎内的坐标
	//CGPoint a_st_engine_location = [[CCDirector sharedDirector] convertToGL:a_st_true_touch_location];
	
	/// 先循环所有 精灵 的 ai函数
	//for (id sprite in m_p_sprite_layer.m_p_props_array) {
//		if ([sprite conformsToProtocol:@protocol(TYAIProtocol)]) {
//			[(id<TYAIProtocol>)sprite ai:delta];
//		}
//	}
	
	return YES;
}
-(void) ccTouchEnded:(UITouch *) touch 
					 withEvent:(UIEvent *) event {
	
}

#pragma mark onEnter方法 
/// 节点调用init方法 以后 会调用此方法
/// 如果使用了 CCTransitionScene, 将会在过渡 开始 以后调用此方法
-(void) onEnter
{
	CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
	
	// must call super here:
	[super onEnter];
}

#pragma mark onEnterTransitionDidFinish方法
/// 节点调用onEnter方法 以后 会调用此方法
/// 如果使用了 CCTransitionScene, 将会在过渡 结束 以后调用此方法
-(void) onEnterTransitionDidFinish
{
	CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
	
	// must call super here:
	[super onEnterTransitionDidFinish];
}

#pragma mark onExit方法
/// 节点调用dealloc方法 之前 会调用此方法
/// 如果使用了 CCTransitionScene, 将会在过渡 结束 以后调用此方法
-(void) onExit
{
	CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
	
	// must call super here:
	[super onExit];
	
	
	/// 将相关数据保存回全局数据区
}








@end
